package project.dbaccesslayer;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;

public class View_SO_Data_VW {
	public static Iterable<String> getData(Connection conn, int limit)
			throws SQLException {
		PreparedStatement s = conn.prepareStatement("SELECT * "
				+ "FROM SO_Data_VW ORDER BY Question_Id LIMIT " + limit);
		final ResultSet r = s.executeQuery();
		return new Iterable<String>() {
			public Iterator<String> iterator() {
				try {
					return new ResultIterator(r);
				} catch (SQLException e) {
					throw new RuntimeException(e);
				}
			}
		};
	}

	private static Map<Integer, Integer> getFeatureMapping(
			ResultSetMetaData metaData) throws SQLException {
		Map<Integer, Integer> map = new TreeMap<Integer, Integer>();

		for (int i = 1; i <= metaData.getColumnCount(); i++) {
			String name = metaData.getColumnLabel(i);
			if (name.startsWith("F_")) {
				System.out.println("Column " + name + " mapped to index "
						+ (map.size() + 1));
				map.put(i, map.size() + 1);
			} else {
				System.out.println("Column " + name + " not mapped");
			}
		}

		return map;
	}

	private static class ResultIterator implements Iterator<String> {
		ResultSet resultSet;
		Map<Integer, Integer> featureMapping;
		private boolean hasNext;

		ResultIterator(ResultSet resultSet) throws SQLException {
			this.resultSet = resultSet;
			this.featureMapping = getFeatureMapping(resultSet.getMetaData());
			this.hasNext = resultSet.next();
		}

		@Override
		public boolean hasNext() {
			return hasNext;
		}

		@Override
		public String next() {
			try {
				StringBuilder sb = new StringBuilder();
				sb.append(resultSet.getLong("Answer_Votes"));
				sb.append(" qid:");
				sb.append(resultSet.getLong("Question_Id"));
				for (int i : featureMapping.keySet()) {
					sb.append(' ');
					sb.append(i);
					sb.append(':');
					sb.append(resultSet.getString(featureMapping.get(i)));
				}

				this.hasNext = resultSet.next();
				return sb.toString();
			} catch (SQLException e) {
				throw new RuntimeException(e);
			}
		}

		public void remove() {
			throw new UnsupportedOperationException();
		}
	}
}
